package com.example.demo.service;

import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;

public class Mahjong {

    /**
     * 34种牌型(不考虑花)，下标表示各个牌型：
     * 0-8表示一万 ~ 九万
     * 9-17表示一筒 ~ 九筒
     * 18-26表示一条 ~ 九条
     * 27-30表示东南西北风
     * 31-33表示中、發、白板
     * 数组上各个值表示，每种牌型的数量
     * 一次按14张(3*4 + 2)牌算，最多只会占有14个位置，最少5个位置
     */
    public static Integer[] myMahjongList = new Integer[34];

    static {
        Arrays.fill(myMahjongList, 0);
    }

    private static void init(String[] mahjongList) {
        Arrays.fill(myMahjongList, 0);
        for (String index : mahjongList) {
            myMahjongList[Integer.valueOf(index)] += 1;
        }
    }

    /**
     * 是否胡牌了
     *
     * @return
     */
    private static Boolean isWinner() {

        // 先找出将牌，这是必要的条件
        for (int i = 0; i < myMahjongList.length; i++) {
            // 一张张牌型遍历
            int mahjong = myMahjongList[i];

            // 分别找到2张牌以上的牌型，做为将牌，试试能不能胡
            if (mahjong >= 2) {
                Integer[] clonedMahjong = myMahjongList.clone();

                // 3张以上的风牌之类的，不拆牌，无意义
                if (mahjong >= 3 && i >= 27) {
                    continue;
                }
                // 将牌移除
                clonedMahjong[i] -= 2;

                // 剩下的牌是否能满足3n的条件
                if (is3NShunzi(clonedMahjong.clone()) || is3NDuizi(clonedMahjong.clone())) {
                    System.out.println("胡牌了");
                    return true;
                }

            }
        }

        System.out.println("没胡牌");

        return false;
    }

    private static boolean is3NShunzi(Integer[] clonedMahjong) {
        boolean canWin = true;
        for (int i = 0; i < 3; i++) {
            if (!canWin) {
                break;
            }

            for (int j = 0; j < 9; j++) {
                if (!canWin) {
                    break;
                }
                int index = 9 * i + j;
                while (clonedMahjong[index] > 0) {
                    // 顺子优先
                    if (j < 7 &&
                            clonedMahjong[index + 1] > 0 &&
                            clonedMahjong[index + 2] > 0) {
                        clonedMahjong[index]--;
                        clonedMahjong[index + 1]--;
                        clonedMahjong[index + 2]--;
                    } else if (clonedMahjong[index] == 3) {
                        clonedMahjong[index] -= 3;

                        // 胡不了
                    } else {
                        canWin = false;
                        break;
                    }
                }
            }
        }

        if (!canWin) {
            return false;
        }

        boolean result = isEmpty(clonedMahjong) || isZi(clonedMahjong);
        System.out.println("顺子优先是否胡牌：" + result);

        return result;
    }

    private static boolean is3NDuizi(Integer[] clonedMahjong) {
        boolean canWin = true;
        for (int i = 0; i < 3; i++) {
            if (!canWin) {
                break;
            }
            for (int j = 0; j < 9; j++) {
                if (!canWin) {
                    break;
                }

                int index = 9 * i + j;
                while (clonedMahjong[index] > 0) {
                    // 对子优先
                    if (clonedMahjong[index] == 3) {
                        clonedMahjong[index] -= 3;

                        // 顺子
                    } else if (j < 7 &&
                            clonedMahjong[index + 1] > 0 &&
                            clonedMahjong[index + 2] > 0) {
                        clonedMahjong[index]--;
                        clonedMahjong[index + 1]--;
                        clonedMahjong[index + 2]--;

                        // 胡不了
                    } else {
                        canWin = false;
                        break;
                    }
                }
            }
        }

        if (!canWin) {
            return false;
        }

        boolean result = isEmpty(clonedMahjong) || isZi(clonedMahjong);
        System.out.println("对子优先是否胡牌：" + result);

        return result;
    }

    /**
     * 剩下的东南西北风等是否都是3对
     *
     * @return
     */
    private static boolean isZi(Integer[] clonedMahjong) {
        for (int i = 27; i < clonedMahjong.length; i++) {
            if (clonedMahjong[i] <= 0) {
                continue;
            }
            // 没有三对以上，胡不了
            if (clonedMahjong[i] < 3) {
                System.out.println("字牌没有3对以上，无法胡牌");
                return false;
            }
        }

        return true;

    }

    private static boolean isEmpty(Integer[] list) {
        return Arrays.stream(list).filter((p) -> p > 0).toArray().length == 0;
    }


    public static void main(String[] args) throws IOException {
        // Integer[] array = new Integer[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12};


        while (true) {
            System.out.print("请输入一组麻将:");
            Scanner sc = new Scanner(System.in);
            String text = sc.nextLine();
            String[] array = text.split(" ");

            System.out.println();

            // 初始化数据
            init(array);

            // 是否胡牌
            isWinner();
        }


    }
}
